package com.record.utils;


import org.apache.commons.math3.ml.clustering.CentroidCluster;
import org.apache.commons.math3.ml.clustering.DoublePoint;
import org.apache.commons.math3.ml.clustering.KMeansPlusPlusClusterer;
import org.apache.commons.math3.ml.distance.EuclideanDistance;

import java.util.List;

public class ClusterUtils {

    /**
     * 使用肘部法自动估计最佳K值
     */
    public static int estimateBestK(List<DoublePoint> points) {
        int sampleSize = points.size();
        int maxK = Math.min(6, sampleSize - 1); // 修复关键点 ✅
        int bestK = 2;
        double lastInertia = Double.MAX_VALUE;

        for (int k = 2; k <= maxK; k++) {
            KMeansPlusPlusClusterer<DoublePoint> clusterer =
                    new KMeansPlusPlusClusterer<>(k, 50, new EuclideanDistance());
            List<CentroidCluster<DoublePoint>> clusters = clusterer.cluster(points);

            double inertia = 0.0;
            for (CentroidCluster<DoublePoint> cluster : clusters) {
                for (DoublePoint p : cluster.getPoints()) {
                    inertia += new EuclideanDistance().compute(cluster.getCenter().getPoint(), p.getPoint());
                }
            }

            if (inertia > lastInertia * 0.95) { // 肘部判定
                break;
            }
            lastInertia = inertia;
            bestK = k;
        }

        return bestK;
    }

}